package com.cos.hospital.tool;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.FrameLayout;

/**
 * @Description: 键盘输入工具类
 * @Author: Kosmos
 * @Date: 2018年2月8日 16:12
 * @Email: KosmoSakura@foxmail.com
 * @eg: 修改日期：2018年09月24日 16:19
 */
public class UKeyboard {
    /**
     * @return true:软键盘已经显示
     * @apiNote 是否显示软件盘
     */
    public boolean isKeyboardShow() {
        return getSupportSoftInputHeight() != 0;
    }

    /**
     * @apiNote 已经显示，则隐藏，反之则显示
     */
    public void openOrhide() {
        imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }

    /**
     * @param editText 接受软键盘输入的视图
     * @apiNote 强制显示键盘
     */
    public void showForce(EditText editText) {
        imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
        editText.setFocusable(true);//可聚焦
        editText.requestFocus();//聚焦
    }

    /**
     * @param editText 接受软键盘输入的视图
     * @apiNote 强制隐藏键盘
     */
    public void hideForce(EditText editText) {
        if (isKeyboardShow()) {
            imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); //强制隐藏键盘
        }
    }

//--------------------------------------------------------------------------------------------------

    private Activity activity;
    private InputMethodManager imm;//软键盘管理类

    /**
     * 外部静态调用
     */
    public static UKeyboard with(Activity activity) {
        UKeyboard keyboard = new UKeyboard();
        keyboard.activity = activity;
        keyboard.imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN |
            WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        return keyboard;
    }

    /**
     * 获取软件盘的高度
     */
    private int getSupportSoftInputHeight() {
        Rect r = new Rect();
        /*
         * decorView是window中的最顶层view，可以从window中通过getDecorView获取到decorView。
         * 通过decorView获取到程序显示的区域，包括标题栏，但不包括状态栏。
         */
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
        //获取屏幕的高度
        int screenHeight = activity.getWindow().getDecorView().getRootView().getHeight();
        //计算软件盘的高度
        int softInputHeight = screenHeight - r.bottom;

        /*
         * 某些Android版本下，没有显示软键盘时减出来的高度总是144，而不是零，
         * 这是因为高度是包括了虚拟按键栏的(例如华为系列)，所以在API Level高于20时，
         * 我们需要减去底部虚拟按键栏的高度（如果有的话）
         */
        if (Build.VERSION.SDK_INT >= 20) {
            softInputHeight = softInputHeight - getSoftButtonsBarHeight();
        }
        return softInputHeight;
    }

    /**
     * @apiNote 底部虚拟按键栏的高度
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private int getSoftButtonsBarHeight() {
        DisplayMetrics metrics = new DisplayMetrics();
        //这个方法获取可能不是真实屏幕的高度
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int usableHeight = metrics.heightPixels;
        //获取当前屏幕的真实高度
        activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
        int realHeight = metrics.heightPixels;
        if (realHeight > usableHeight) {
            return realHeight - usableHeight;
        } else {
            return 0;
        }
    }

//--------------------------------------------------------------------------------------------------

    /**
     * 解决键盘档住输入框
     * Created by SmileXie on 2017/4/3.
     */
    public static class SoftHideKeyBoardUtil {
        private View mChildOfContent;
        private int usableHeightPrevious;
        private FrameLayout.LayoutParams frameLayoutParams;
        //为适应华为小米等手机键盘上方出现黑条或不适配
        private int contentHeight;//获取setContentView本来view的高度
        private boolean isfirst = true;//只用获取一次
        private int statusBarHeight;//状态栏高度

        private SoftHideKeyBoardUtil(Activity activity) {
            //1､找到Activity的最外层布局控件，它其实是一个DecorView,它所用的控件就是FrameLayout
            FrameLayout content = activity.findViewById(android.R.id.content);
            //2､获取到setContentView放进去的View
            mChildOfContent = content.getChildAt(0);
            //3､给Activity的xml布局设置View树监听，当布局有变化，如键盘弹出或收起时，都会回调此监听
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                //4､软键盘弹起会使GlobalLayout发生变化
                public void onGlobalLayout() {
                    if (isfirst) {
                        contentHeight = mChildOfContent.getHeight();//兼容华为等机型
                        isfirst = false;
                    }
                    //5､当前布局发生变化时，对Activity的xml布局进行重绘
                    possiblyResizeChildOfContent();
                }
            });
            //6､获取到Activity的xml布局的放置参数
            frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
        }

        public static void assistActivity(Activity activity) {
            new SoftHideKeyBoardUtil(activity);
        }

        // 获取界面可用高度，如果软键盘弹起后，Activity的xml布局可用高度需要减去键盘高度
        private void possiblyResizeChildOfContent() {
            //1､获取当前界面可用高度，键盘弹起后，当前界面可用布局会减少键盘的高度
            int usableHeightNow = computeUsableHeight();
            //2､如果当前可用高度和原始值不一样
            if (usableHeightNow != usableHeightPrevious) {
                //3､获取Activity中xml中布局在当前界面显示的高度
                int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
                //4､Activity中xml布局的高度-当前可用高度
                int heightDifference = usableHeightSansKeyboard - usableHeightNow;
                //5､高度差大于屏幕1/4时，说明键盘弹出
                if (heightDifference > (usableHeightSansKeyboard / 4)) {
                    // 6､键盘弹出了，Activity的xml布局高度应当减去键盘高度
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
                    } else {
                        frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                    }
                } else {
                    frameLayoutParams.height = contentHeight;
                }
                //7､ 重绘Activity的xml布局
                mChildOfContent.requestLayout();
                usableHeightPrevious = usableHeightNow;
            }
        }

        private int computeUsableHeight() {
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
            // 全屏模式下：直接返回r.bottom，r.top其实是状态栏的高度
            return (r.bottom - r.top);
        }
    }
}
